home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_100
/
185_01
/
hsh.c
< prev
next >
Wrap
Text File
|
1985-08-19
|
25KB
|
863 lines
/* hsh -- ZCPR3 history shell */
/* copyright 1985 Michael M Rubenstein */
/* version 1.1 6 Oct 85 */
/* Modifications */
/* 1.1 (MMR) Fixed handling of firsthist on wrap around. Previous */
/* did not reset to 0, which could result in the program hanging */
/* if a search was done for a leading string which was not in the */
/* history. */
#include <sysio.h>
#include <fcb.h>
#define SHNAME "HSH.COM" /* default name */
#define VARFILE "HSH.VAR" /* history file */
#define DEFNHIST 10 /* default number of history lines */
/* some interesting characters */
#define CTL 0x1f
#define NUL 0
#define CTLA (CTL & 'A')
#define CTLC (CTL & 'C')
#define CTLD (CTL & 'D')
#define CTLE (CTL & 'E')
#define CTLF (CTL & 'F')
#define CTLG (CTL & 'G')
#define BEL CTLG
#define BS (CTL & 'H')
#define CTLJ (CTL & 'J')
#define LF CTLJ
#define CR (CTL & 'M')
#define CTLL (CTL & 'L')
#define CTLP (CTL & 'P')
#define CTLQ (CTL & 'Q')
#define CTLR (CTL & 'R')
#define CTLS (CTL & 'S')
#define CTLT (CTL & 'T')
#define CTLU (CTL & 'U')
#define CTLV (CTL & 'V')
#define CTLW (CTL & 'W')
#define CTLX (CTL & 'X')
#define CTLY (CTL & 'Y')
#define CTLZ (CTL & 'Z')
#define ESC (CTL & '[')
#define DEL 0x7f
extern unsigned z3env; /* pointer to ZCPR3 environment */
extern FCB dfcb_; /* default CP/M FCB */
int curdir = FALSE; /* if TRUE, search current dir */
int nhist = DEFNHIST; /* number of history lines */
int firsthist = 0; /* index of first history line */
int lasthist = 0; /* index of one past last line */
int drive, user; /* current drive/user */
int rdrive, ruser; /* root drive/user */
int linepos; /* position on CRT line */
int maxpos; /* max pos on CRT line used */
int maxcols; /* columns on CRT display */
char *cur; /* pointer to current char in */
/* line being edited */
char *line; /* pointer to start of line */
/* being edited */
char *maxcur; /* end of line */
char *gethline(); /* get a line from the history */
char *puthline(); /* put a line to the history */
FCB *gefcb(); /* get ZCPR3 external FCB */
char *getcrt(); /* get ZCPR3 terminal data */
main()
{
static FCB *efcb; /* FCB for shell name */
static char shname[13]; /* shell name */
static char *s;
int du;
static int c;
static int i;
static int n = -1; /* value of command line arg */
char aline[256];
line = aline; /* cheap way to allocate mem */
maxcur = line + 255; /* end of line */
/* if there is a command line argument, evaluate and save it */
if (isdigit(dfcb_.name1.fname[0]))
{
n = atoi(dfcb_.name1.fname);
if (n < 0)
error("hsh: number of history lines too large.");
}
else
if (dfcb_.name1.fname[0] != ' ')
error("syntax: hsh [<number of history lines to keep>]");
if (z3env == 0)
error("hsh: ZCPR3 required.");
/* clear external command line. abort if none */
if (!clcl())
error("hsh: ZCPR3 external command line required.");
/* find where we are and where root dir is for later use */
drive = curdsk();
user = getusr();
du = groot();
rdrive = du >> 8;
ruser = du & 8;
/* if not invoked as a shell, install as shell */
if (!qsh())
{
/* if no external FCB, use default name */
if ((efcb = gefcb()) == NULL)
{
setfcb(SHNAME, &dfcb_);
efcb = &dfcb_;
}
/* find where program is and set up name with drive/user */
if ((du = pfnd(efcb, curdir)) == -1)
error("hsh: Cannot find shell program.");
shname[0] = (du >> 8) + 'A';
du &= 0xff;
shname[1] = du / 10 + '0';
shname[2] = du % 10 + '0';
shname[3] = ':';
for (i = 0; i < 8; ++i)
{
if ((c = (efcb->name1.fname[i] & 0x7f)) == ' ')
break;
shname[4 + i] = c;
}
shname[4 + i] = '\0';
if (shpsh(shname))
error("hsh: Cannot install shell.");
ps("HSH Version 1.0 (1 Oct 85) installed\r\n");
/* if a command line arg was entered, set up history file with number */
/* of lines to keep */
if (n >= 0)
{
nhist = n;
/* go to the right place */
select(rdrive);
setusr(ruser);
setfcb(VARFILE, &dfcb_);
delete(&dfcb_);
if (make(&dfcb_) == 0xff)
sherror("hsh: Cannot create HSH.VAR.");
puthist();
}
/* exit after installing shell, so will work from submit file */
return;
}
/* set ZCPR3 command status message so next program won't think it's */
/* a shell (needed since we don't warm boot on exit) */
pcst(0);
maxcols = *getcrt() & 0xff;
gethist(); /* get history */
getcmd(); /* handle a command */
puthist(); /* save history */
}
/* get the history */
gethist()
{
/* first record in history file keeps parameters */
struct { int f_nhist, f_fhist, f_lhist;
char f_fill[126];
} fnhist;
/* go to the right place */
select(rdrive);
setusr(ruser);
setfcb(VARFILE, &dfcb_);
/* if there's a history file, read it in and set firsthist and lasthist */
if (open(&dfcb_) != 0xff)
{
setdma(&fnhist);
if (!rdseq(&dfcb_))
{
nhist = fnhist.f_nhist;
firsthist = fnhist.f_fhist;
lasthist = fnhist.f_lhist;
}
}
else
/* if no history file, create it */
if (make(&dfcb_) == 0xff)
sherror("hsh: Cannot create HSH.VAR.");
}
/* put the history paramters to file */
puthist()
{
/* first record in history file keeps parameters */
struct { int f_nhist, f_fhist, f_lhist;
char f_fill[126];
} fnhist;
fnhist.f_nhist = nhist;
fnhist.f_fhist = firsthist;
fnhist.f_lhist = lasthist;
setdma(&fnhist);
dfcb_.rrec = 0;
if (wrran(&dfcb_))
sherror("hsh: Error writing HSH.VAR.");
if (close(&dfcb_) == 0xff)
sherror("hsh: Error closing HSH.VAR");
/* return to where we were */
select(drive);
setusr(user);
}
/* get a history line. returns pointer to line for convenience. */
char *gethline(line, n)
char *line;
int n;
{
dfcb_.rrec = 2 * n + 1;
setdma(line);
if (rdran(&dfcb_))
sherror("hsh: Cannot read HSH.VAR.");
++dfcb_.rrec;
setdma(line + 128);
if (rdran(&dfcb_))
sherror("hsh: Cannot read HSH.VAR.");
return line;
}
/* put a history line. returns pointer to line for convenience. */
char *puthline(line, n)
char